using System;
using System.Collections.Generic;
using System.Text;
using NUnit.Framework;
using MapCop;
using MapCop.Test.Helpers;

namespace MapCop.Test
{
    [TestFixture]
    public class MapTest : IDisposable
    {
        TestFile simpleMap;
        Map testSimple;
        string mapFilename = "MapTestTestMap.btm";

        public MapTest()
        {
        }

        [TestFixtureSetUp]
        public void FixtureSetup()
        {
            simpleMap = new TestFile(mapFilename, 
                "MapCop.Test.TestData.SimpleMap.btm");
        }
        [TestFixtureTearDown]
        public void FixtureTeardown()
        {
            simpleMap.Dispose();
        }
        #region Setup & Teardown
        [SetUp]
        public void Setup()
        {
            testSimple = new Map(simpleMap.FileName);
        }

        [TearDown]
        public void TearDown()
        {
            testSimple = null;
        }
        #endregion

        [Test]
        public void ScriptPrecedence()
        {
            Assert.IsNotNull(testSimple.ScriptTypePrecedences);
            foreach(ScriptTypePrecedence loopScript in testSimple.ScriptTypePrecedences)
            {
                Assert.IsTrue(loopScript.Enabled);
                Assert.AreSame(testSimple,loopScript.Map);
            }
        }

        [Test]
        public void CreateMap()
        {
            Map btm = new Map(simpleMap.FileName);

            Assert.IsNotNull(btm);
        }

        [Test]
        [ExpectedException(typeof(System.IO.FileNotFoundException), 
            ExpectedMessage="Unable to locate map file BogusFileName.btm.")]
        public void RequireFileToExist()
        {
            Map btm = new Map("BogusFileName.btm");
        }

        [Test]
        public void PagesCollection()
        {
            List<MapPage> pages = testSimple.Pages;

            Assert.AreEqual(1,pages.Count,"Wrong Page Count");
            Assert.AreEqual("Page 1",pages[0].Name,"Wrong Name");
            Assert.IsNotNull(pages[0].Map,"Map Null");
            Assert.AreSame(testSimple,pages[0].Map,"Missing Map");
        }
        [Test]
        public void AdditionalMapProperties()
        {
            Assert.AreEqual("2.0", testSimple.MapperVersion, "Mapper Version");
            Assert.AreEqual("2", testSimple.Version, "Version");
            Assert.AreEqual(100,testSimple.XRange, "XRange");
            Assert.AreEqual(420,testSimple.YRange, "YRange");
            Assert.IsTrue(testSimple.OmitXmlDeclaration, "OmitXmlDeclare");
            Assert.IsFalse(testSimple.TreatElementsAsRecords, "TreatElementsAsRecords");
            Assert.IsTrue(testSimple.OptimizeValueMapping, "Opt. Value Mapping");
            Assert.IsTrue(testSimple.GenerateDefaultFixedNodes, "Gen Fixed Nodes");
            Assert.IsFalse(testSimple.CopyPIs, "CopyPIs");
            Assert.IsTrue(testSimple.IgnoreNamespacesForLinks,"Ignore Namespace");
            Assert.AreEqual("xml",testSimple.Method,"Method");
            Assert.AreEqual("1.0",testSimple.XmlVersion,"Xml Version");
        }

        [Test]
        public void LinkToFunctoidCrosswalk()
        {
            MapPageLink testLink = testSimple.Pages[0].Links[0];
            MapPageFunctoid testFunc = testSimple.Pages[0].Functoids[1];

            Assert.AreSame(testFunc,testLink.LinkTo.Functoid);
        }

        [Test]
        public void FunctoidParameters()
        {
            MapPageFunctoid func = testSimple.Pages[0].Functoids[0];

            Assert.AreEqual(3, func.Parameters.Count, "Wrong Parameter Count");
            Assert.AreEqual(ParameterType.Link,func.Parameters[0].Type,"Wrong Parameter Type");
            Assert.AreEqual(new Guid("{5BE3B6AE-31C4-4827-A721-0694CA5973AE}"),func.Parameters[0].Guid, "Wrong Guid");
            Assert.AreEqual("2",func.Parameters[0].Value,"Wrong Value");

            Assert.IsNotNull(func.Parameters[0].Link,"Link not null");
            Assert.AreSame(func.Page.Links[1], func.Parameters[0].Link,"Link not found.");

            Assert.AreSame(testSimple, func.Parameters[0].Map);
            Assert.AreSame(testSimple.Pages[0], func.Parameters[0].Page);
            Assert.AreSame(testSimple.Pages[0].Functoids[0],func.Parameters[0].Functoid);
        }

        [Test]
        public void PageFunctoidsCollection()
        {
            List<MapPageFunctoid> funcs = testSimple.Pages[0].Functoids;

            Assert.AreEqual(2,funcs.Count,"Wrong Functoids Count");
            Assert.IsNotNull(funcs[0],"Test Functoid Null");

            Assert.AreEqual(1,funcs[0].ID,"Wrong Functoid Id");
            Assert.AreEqual(55, funcs[0].XCell, "Wrong Functoid XCell");
            Assert.AreEqual(214, funcs[0].YCell, "Wrong Functoid YCell");
            Assert.AreEqual(new Guid("{D416A0C2-C51A-4AEA-A712-5E0434808F54}"),funcs[0].ClsId, "Wrong ClsId");
            Assert.AreEqual(24602, funcs[0].FunctoidId, "Wrong FunctoidId");
            Assert.AreEqual("If ... Else", funcs[0].Name, "Wrong Name");
            Assert.AreEqual("",funcs[0].Label,"Wrong Label");

            Assert.AreSame(testSimple, funcs[0].Map);
            Assert.AreSame(testSimple.Pages[0], funcs[0].Page);

        }

        [Test]
        public void PageLinksCollection()
        {
            List<MapPageLink> links = testSimple.Pages[0].Links;

            Assert.AreEqual(6,links.Count, "Wrong Link Count");
            Assert.IsNotNull(links[0], "Test Link Null");
            Assert.AreEqual(1,links[0].ID,"Wrong Link Id");
            Assert.AreEqual("TestLabel",links[0].Label,"Wrong Label");

            Assert.AreEqual("/*[local-name()='<Schema>']/*[local-name()='Root']/*[local-name()='Record']", links[0].LinkFrom.Text, "Wrong LinkFrom Text");
            Assert.AreEqual(LinkType.LinkFrom, links[0].LinkFrom.LinkType, "Wrong LinkFrom LinkType");
            Assert.AreSame(testSimple,links[0].LinkFrom.Map);
            Assert.AreSame(testSimple.Pages[0], links[0].LinkFrom.Page);
            Assert.AreSame(links[0], links[0].LinkFrom.Link);

            Assert.AreEqual("2", links[0].LinkTo.Text, "Wrong LinkTo Text");
            Assert.AreEqual(LinkType.LinkTo, links[0].LinkTo.LinkType, "Wrong LinkTo LinkType");
            Assert.AreSame(testSimple, links[0].LinkTo.Map);
            Assert.AreSame(testSimple.Pages[0], links[0].LinkTo.Page);
            Assert.AreSame(links[0], links[0].LinkTo.Link);
        }

        #region IDisposable Members

        public void Dispose()
        {
            simpleMap.Dispose();
        }

        #endregion
    }
}
